package org.shuma.goods.service.impl;

import com.alipay.sofa.runtime.api.annotation.SofaReference;
import com.alipay.sofa.runtime.api.annotation.SofaReferenceBinding;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.shuma.goods.domain.DTO.SearchProductDTO;
import org.shuma.goods.domain.DTO.UpdateStatus;
import org.shuma.goods.domain.entity.ProductBasicInfo;
import org.shuma.goods.mapper.ProductBasicInfoDao;
import org.shuma.goods.mapper.ProductBasicInfoMapper;
import org.shuma.goods.service.ProductBasicInfoService;
import org.shuma.goods.service.ProductDetailsInfoService;
import org.shuma.goods.service.ProductTypeService;
import org.shuma.proxy.facade.Proxy;
import org.shuma.user.facade.UserFacade;
import org.shuma.user.vo.UserVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;


@Service
public class ProductBasicInfoServiceImpl extends ServiceImpl<ProductBasicInfoMapper, ProductBasicInfo>
        implements ProductBasicInfoService {
    private UserFacade userFacade;
    @SofaReference(interfaceType = Proxy.class,uniqueId = "${service.proxy.unique.id}",
            binding = @SofaReferenceBinding(bindingType = "bolt"))

    private Proxy proxy;
    @Autowired
    private ProductDetailsInfoService productDetailsInfoService;
    @Autowired
    private ProductBasicInfoMapper productBasicInfoMapper;
    @Resource
    private ProductBasicInfoDao productBasicInfomapper;

    @Resource
    private RedissonClient redissonClient;

    @Resource
    private ProductTypeService productTypeService;

    @Override
    public ProductBasicInfo getProductBasicInfo(Integer productId,UserVo userVo) {
        return productBasicInfoMapper.selectById(productId);
    }


    /**
     * 通过ID查询单条数据
     *
     * @param productId 主键
     * @return 实例对象
     */
    @Override
    public ProductBasicInfo queryById(Long productId) {
        return this.productBasicInfomapper.queryById(productId);
    }

    /**
     * 分页查询
     *
     * @param productBasicInfo 筛选条件
     * @param pageRequest      分页对象
     * @return 查询结果
     */
    @Override
    public org.springframework.data.domain.Page<ProductBasicInfo> queryByPage(ProductBasicInfo productBasicInfo, PageRequest pageRequest) {
        long total = this.productBasicInfomapper.count(productBasicInfo);
        return new PageImpl<ProductBasicInfo>(this.productBasicInfomapper.queryAllByLimit(productBasicInfo, pageRequest), pageRequest, total);
    }

//    /**
//     * 新增数据
//     *
//     * @param productBasicInfo 实例对象
//     * @return 实例对象
//     */
//    @Override
//    public ProductBasicInfo insert(ProductBasicInfo productBasicInfo) {
//        ProductBasicInfo basicInfo = this.productBasicInfomapper.insert(productBasicInfo); TODO 错误
//        Long productId = basicInfo.getProductId();
//        Long proxyId = productBasicInfo.getProxyId();
//        ProductProxy productProxy = new ProductProxy();
//        productProxy.setProxyId(proxyId);
//        productProxy.setProductId(productId);
//        proxy.addProxy(productProxy);
//        return productBasicInfo;
//    }

    /**
     * 修改数据
     *
     * @param productBasicInfo 实例对象
     * @return 实例对象
     */
    @Override
    public ProductBasicInfo update(ProductBasicInfo productBasicInfo) {
        ProductBasicInfo productBasicInfo1 = productBasicInfo;
        productBasicInfo1.setProductId(null);
        if (productBasicInfo.getPDetailsId() == null || productBasicInfo1==null){
            throw new RuntimeException();
        }
        this.productBasicInfomapper.update(productBasicInfo);
        return this.queryById(productBasicInfo.getProductId());
    }

    /**
     * 通过主键删除数据

     * @return 是否成功
     */
    @Override
    public boolean deleteById(List<Long> idList) {
        int count = 0;
        for (Long productId : idList) {
            org.shuma.goods.domain.entity.ProductBasicInfo productBasicInfo = productBasicInfomapper.queryById(productId);
            productDetailsInfoService.deleteById(productBasicInfo.getPDetailsId());
            productBasicInfomapper.deleteById(productId);
            proxy.deleteProxy(productId);
            count++;
        }
        return count == idList.size();}

    @Override
    public Page<ProductBasicInfo> getProductBasicInfoList(SearchProductDTO searchProductDTO, Integer pageNum, Integer pageSize, UserVo userVo) {
        Page<ProductBasicInfo> page = new Page<>(pageNum, pageSize);
        Long userId = userVo.getId();
        LambdaQueryWrapper<ProductBasicInfo> queryWrapper = new LambdaQueryWrapper<>();
        if(userVo != null && userVo.getUserRole() == 0)
            queryWrapper.eq(ProductBasicInfo::getCreator,userId);
        if(searchProductDTO.getProductName() != null && searchProductDTO.getProductName() != "")
            queryWrapper.like(ProductBasicInfo::getProductName,searchProductDTO.getProductName());
        if(searchProductDTO.getRaiId() != null)
            queryWrapper.like(ProductBasicInfo::getRaiId,searchProductDTO.getRaiId());
        if(searchProductDTO.getTimeOn() != null && !searchProductDTO.getTimeOn().equals(""))
            queryWrapper.ge(ProductBasicInfo::getTimeOn,searchProductDTO.getTimeOn());
        if(searchProductDTO.getTimeOff() != null && !searchProductDTO.getTimeOff().equals(""))
            queryWrapper.le(ProductBasicInfo::getTimeOff,searchProductDTO.getTimeOff());
        if(searchProductDTO.getRaiId() != null)
            queryWrapper.eq(ProductBasicInfo::getProductCheckState,searchProductDTO.getProductCheckState());
        if(searchProductDTO.getRaiId() != null)
            queryWrapper.eq(ProductBasicInfo::getProxyId,searchProductDTO.getProxyId());
        List<ProductBasicInfo> productBasicInfos = productBasicInfoMapper.selectList(queryWrapper);
        this.page(page,queryWrapper);

        return page;
    }



    public Page<ProductBasicInfo> getProductStatus(Integer productId,Integer pageNum, Integer pageSize,UserVo userVo) {
        if (userVo != null && userVo.getUserRole() == 0) {
            Long userId = userVo.getId();
            Page<ProductBasicInfo> page = new Page<>(pageNum, pageSize);
            QueryWrapper<ProductBasicInfo> queryWrapper = new QueryWrapper<ProductBasicInfo>().eq("product_check_state", productId)
                    .eq("creator",userId);
//            List<ProductBasicInfo> productBasicInfos = productBasicInfoMapper.selectList(queryWrapper);
            this.page(page, queryWrapper);
            return page;
        } else {
            Page<ProductBasicInfo> page = new Page<>(pageNum, pageSize);
            QueryWrapper<ProductBasicInfo> queryWrapper = new QueryWrapper<ProductBasicInfo>().eq("product_check_state", productId);
//            List<ProductBasicInfo> productBasicInfos = productBasicInfoMapper.selectList(queryWrapper);
            this.page(page, queryWrapper);
            return page;
        }
    }







    /**
     * 更新商品状态
     * @param updateStatus
     * @param userVo
     * @return
     */
    @Override
    public Boolean updateStatus(UpdateStatus updateStatus, UserVo userVo) {

        String redisKey = String.format("goods:%s",userVo.getId());//只有一个线程能获取到锁
        RLock lock = redissonClient.getLock(redisKey);
        try{
            //抢到锁并执行
            while(true){
                if(lock.tryLock(0,-1, TimeUnit.MICROSECONDS)){
                    System.out.println("getLock: "+Thread.currentThread().getId());
                    ProductBasicInfo productBasicInfo = new ProductBasicInfo();
                    BeanUtils.copyProperties(updateStatus,productBasicInfo);
                    return this.updateById(productBasicInfo);
                }
            }
        }catch (InterruptedException e){
            log.error("updateGoodsStatus error", e);
            return false;
        }finally {
            //只能释放自己的锁
            if(lock.isHeldByCurrentThread()){
                System.out.println("unLock: " + Thread.currentThread().getId());
                lock.unlock();
            }
        }

    }




}
